/*
 * Winkel1Projection.java
 *
 * Created on July 17, 2007, 9:04 AM
 *
 */

package ika.proj;

import ika.proj.MapMath;
import com.jhlabs.map.proj.ProjectionException;
import com.jhlabs.map.proj.PseudoCylindricalProjection;
import java.awt.geom.Point2D;

/**
 *
 * Ported from Proj4 by Bernhard Jenny, Institute of Cartography, ETH Zurich.
 */
public class Winkel1Projection extends PseudoCylindricalProjection {
    
    /**
     * latitude of true scale on central meridian 
     * default is 50 degree and 28 minutes. This differs from the default value 
     * of proj4, which uses 0. 0 is not appropriate, as with 0, the Winkel I is
     * equal to Eckert V
     */
    private double phi1 = Math.toRadians(50. + 28. / 60.);
    
    /**
     * cosine of latitude of true scale on central meridian
     */
    private double cosphi1 = Math.cos(phi1);
    
    /** Creates a new instance of Winkel1Projection */
    public Winkel1Projection() {
    }
    
    public Point2D.Double project(double lplam, double lpphi, Point2D.Double out) {
        
        out.x = .5 * lplam * (cosphi1 + Math.cos(lpphi));
	out.y = lpphi;
        return out;
    
    }
    
    public Point2D.Double projectInverse(double xyx, double xyy, Point2D.Double out) {
        
        out.y = xyy;
	out.x = 2. * xyx / (this.cosphi1 + Math.cos(xyy));
        return out;
    
    }
    
    public boolean hasInverse() {
        return true;
    }
    
    public String toString() {
        return "Winkel I";
    }
    
    public void setLatitudeOfTrueScale(double phi1) {
        if (phi1 < -MapMath.HALFPI || phi1 > MapMath.HALFPI)
            throw new ProjectionException();
        this.phi1 = phi1;
        this.cosphi1 = Math.cos(this.phi1);
    }
}
